﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;

namespace MacroApp
{
    /// <summary>
    /// An useful class to read/write/delete/count registry keys
    /// </summary>
    public class Registrys
    {
        private const string RegKey = @"Software\Microsoft\Windows\CurrentVersion\App Paths";
        public  const string m_MacroKey = "AccessVBOM";
        /// <summary>
        /// define enum
        /// </summary>
        public enum OfficeComponent
        {
            Word,
            Excel,
            PowerPoint,
            Outlook,
            Access
        }
        public static void ProcessRegistry()
        {            
            bool pathNotFound = false;
            bool RestartComputer = false;
            bool RestartComputerWord = false;
            if (!Registrys.Read(m_MacroKey, "11.0", ref pathNotFound))
            {
                if (!pathNotFound)
                {
                    string value = "1";
                    bool res = Registrys.Write(m_MacroKey, value, "11.0");

                    if (res)
                    {
                        RestartComputer = true;
                    }
                }
            }


            if (!Registrys.Read(m_MacroKey, "12.0", ref pathNotFound))
            {
                if (!pathNotFound)
                {
                    string value = "1";
                    bool res = Registrys.Write(m_MacroKey, value, "12.0");

                    if (res)
                    {
                        RestartComputer = true;
                    }
                }
            }

            pathNotFound = false;

            if (!Registrys.Read(m_MacroKey, "14.0", ref pathNotFound))
            {
                if (!pathNotFound)
                {
                    string value = "1";
                    bool res = Registrys.Write(m_MacroKey, value, "14.0");

                    if (res)
                    {
                        RestartComputer = true;
                    }
                }
            }
            ////
            // toan them, truong hop ko dang ky duoc, 3 truong hop tren
            int version = 0;
            if (pathNotFound)
            {
                version = (Registrys.GetMajorVersion(Registrys.GetComponentPath(OfficeComponent.Excel)));
                if (!Registrys.Read(m_MacroKey, version.ToString() + ".0", ref pathNotFound))
                {
                    if (!pathNotFound)
                    {
                        string value = "1";
                        bool res = Registrys.Write(m_MacroKey, value, version.ToString() + ".0");

                        if (res)
                        {
                            RestartComputer = true;
                        }
                    }
                }
            }

            pathNotFound = false;

            //Word

            version = (Registrys.GetMajorVersion(Registrys.GetComponentPath(OfficeComponent.Word)));
            if (!Registrys.ReadWord(Registrys.m_MacroKey, version.ToString() + ".0", ref pathNotFound))
            {
                if (!pathNotFound)
                {
                    string value = "1";
                    bool res = Registrys.WriteWord(Registrys.m_MacroKey, value, version.ToString() + ".0");
                    if (res)
                    {
                        RestartComputerWord = true;
                    }
                }
            }

            if (RestartComputer == true || RestartComputerWord == true)
            {
                if (MessageBox.Show("Cập nhật cấu hình thành công, vui lòng khởi động lại máy để xóa được macro", "Cập nhật cấu hình", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    System.Diagnostics.Process.Start("ShutDown", "/r");
                }
            }
        }

        public static string GetComponentPath(OfficeComponent _component)
        {
            string toReturn = string.Empty;
            string _key = string.Empty;

            switch (_component)
            {
                case OfficeComponent.Word:
                    _key = "winword.exe";
                    break;
                case OfficeComponent.Excel:
                    _key = "excel.exe";
                    break;
                case OfficeComponent.PowerPoint:
                    _key = "powerpnt.exe";
                    break;
                case OfficeComponent.Outlook:
                    _key = "outlook.exe";
                    break;
            }

            //looks inside CURRENT_USER:
            RegistryKey _mainKey = Registry.CurrentUser;
            try
            {
                _mainKey = _mainKey.OpenSubKey(RegKey + "\\" + _key, false);
                if (_mainKey != null)
                {
                    toReturn = _mainKey.GetValue(string.Empty).ToString();
                }
            }
            catch
            { }

            //if not found, looks inside LOCAL_MACHINE:
            _mainKey = Registry.LocalMachine;
            if (string.IsNullOrEmpty(toReturn))
            {
                try
                {
                    _mainKey = _mainKey.OpenSubKey(RegKey + "\\" + _key, false);
                    if (_mainKey != null)
                    {
                        toReturn = _mainKey.GetValue(string.Empty).ToString();
                    }
                }
                catch
                {
                }
            }

            //closing the handle:
            if (_mainKey != null)
                _mainKey.Close();

            return toReturn;
        }

        /// <summary>
        /// Gets the major version of the path. if file not found (or any other exception occures
        /// - returns 0
        /// </summary>
        public static int GetMajorVersion(string _path)
        {
            int toReturn = 0;
            if (File.Exists(_path))
            {
                try
                {
                    FileVersionInfo _fileVersion = FileVersionInfo.GetVersionInfo(_path);
                    toReturn = _fileVersion.FileMajorPart;
                }
                catch
                { }
            }

            return toReturn;
        }      

        public static bool Read(string KeyName, string version, ref bool blPathNotFound)
        {
            // open the registry key
            string supkey = string.Format(@"Software\\Microsoft\\Office\\" + version + "\\Excel\\Security");
            RegistryKey rk = Registry.CurrentUser.OpenSubKey(supkey);
            if (rk == null)
            {
                blPathNotFound = true;
                return false;
            }
            else
            {
                try
                {
                    string value = rk.GetValue(KeyName).ToString();
                    if (!value.Equals("1"))
                    {
                        return false;
                    }                   
                }
                catch
                {
                    return false;
                }
            }

            return true;
        }       
        public static bool Write(string KeyName, string Value, string version)
        {
            string supkey = string.Format(@"Software\\Microsoft\\Office\\" + version + "\\Excel\\Security");
            try
            {
                RegistryKey regKeyAppRoot = Registry.CurrentUser.CreateSubKey(supkey);
                regKeyAppRoot.SetValue(KeyName, Value);                
                return true;
            }
            catch
            {
                return false;
            }
        }
        #region Word
        public static bool ReadWord(string KeyName, string version, ref bool blPathNotFound)
        {
            // open the registry key
            string supkey = string.Format(@"Software\\Microsoft\\Office\\{0}\\{1}\\Security",version, OfficeComponent.Word);
            RegistryKey rk = Registry.CurrentUser.OpenSubKey(supkey);
            if (rk == null)
            {
                blPathNotFound = true;
                return false;
            }
            else
            {
                try
                {
                    string value = rk.GetValue(KeyName).ToString();
                    if (!value.Equals("1"))
                    {
                        return false;
                    }
                }
                catch
                {
                    return false;
                }
            }

            return true;
        }
        public static bool WriteWord(string KeyName, string Value, string version)
        {
            string supkey = string.Format(@"Software\\Microsoft\\Office\\{0}\\{1}\\Security",version, OfficeComponent.Word);
            try
            {
                RegistryKey regKeyAppRoot = Registry.CurrentUser.CreateSubKey(supkey);
                regKeyAppRoot.SetValue(KeyName, Value);
                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion
    }
}
